package com.ziiwee.reduce.describe;

import com.ziiwee.reduce.describe.register.DescribeRegister;
import com.ziiwee.reduce.describe.types.TypeProviderContext;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ziiwee
 * @date 2020/8/13
 */
public class DefaultDescribeHolder implements DescribeHolder {

    private final Map<String, ControllerDescribe> describeMap = new HashMap<>();
    private final Map<String, TypeDescribe> typeMap;


    public DefaultDescribeHolder(List<DescribeRegister> registers, TypeProviderContext context) {
        registers.sort(Comparator.comparing(DescribeRegister::getOrder));
        for (DescribeRegister register : registers) {
            for (ControllerDescribe describe : register.getDescribes()) {
                describeMap.put(describe.getId(), describe);
            }
        }
        describeMap.forEach((k, v) -> render(context, v));
        this.typeMap = context.getCache();
    }

    @Override
    public Map<String, ControllerDescribe> getControllers() {

        return describeMap;
    }

    @Override
    public ControllerDescribe getController(String id) {
        return describeMap.get(id);
    }

    @Override
    public Map<String, TypeDescribe> getTypes() {
        return typeMap;
    }

    @Override
    public TypeDescribe getType(String id) {
        return typeMap.get(id);
    }

    private void render(TypeProviderContext context, ControllerDescribe endpoint) {
        context.render(endpoint.getType());
        if (endpoint.getSubjectType() != null) {
            context.render(endpoint.getSubjectType());
        }
        endpoint.getHandlers().forEach(handler -> {
            context.render(handler.getType());
            handler.getParameters().forEach((k, param) -> {
                param.forEach(p -> context.render(p.getType()));
            });
        });
    }

}
